/**
 * Copyright (c) 2011 eelpo.com
 * All rights reserved.
 */
package com.eelpo.cmmp.uac.services.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.eelpo.cmmp.core.exception.ServiceException;
import com.eelpo.cmmp.uac.dao.IEntityManageDao;
import com.eelpo.cmmp.uac.dao.IEntityRelationManageDao;
import com.eelpo.cmmp.uac.dao.IUserManageDao;
import com.eelpo.cmmp.uac.dao.entity.TEntity;
import com.eelpo.cmmp.uac.dao.entity.TEntityRelation;
import com.eelpo.cmmp.uac.dao.entity.TEntityType;
import com.eelpo.cmmp.uac.dao.entity.TUser;
import com.eelpo.cmmp.uac.dao.vo.Entity;
import com.eelpo.cmmp.uac.dao.vo.enumed.Status;
import com.eelpo.cmmp.uac.services.IEntityManageService;
import com.eelpo.common.util.BlankUtils;

/**
 * <pre>
 * 业务实体服务管理具体实现
 * </pre>
 * 
 * @author <a href="mailto:Brian@eelpo.com">汪洪州</a>
 * @since 1.0
 */
@Service
public class EntityManageService implements IEntityManageService {

	@Resource
	protected IUserManageDao userManageDao;
	
	@Resource
	protected IEntityManageDao entityManageDao;

	@Resource
	protected IEntityRelationManageDao entityRelationManageDao;

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#getEntityById(java.
	 *      lang.String)
	 */
	@Override
	public Entity getEntityById(String id) throws ServiceException {
		return null;
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#getEntityByCode(java
	 *      .lang.String)
	 */
	@Override
	public Entity getEntityByCode(String code) throws ServiceException {

		TEntity tentity = entityManageDao.getEntityByCode(code);

		if (BlankUtils.isBlank(tentity)) {
			throw new ServiceException("实体[" + code + "]不存在！");
		}

		return po2vo(tentity);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#checkExist(java.lang
	 *      .String)
	 */
	@Override
	public boolean checkExist(String code) throws ServiceException {
		return entityManageDao.checkExist(code);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#addEntity(com.eelpo
	 *      .cmmp.uac.dao.vo.Entity)
	 */
	@Override
	public String addEntity(Entity entity) throws ServiceException {

		// 检查业务实体编码是否存在
		if (entityManageDao.checkExist(entity.getCode())) {
			throw new ServiceException("实体[" + entity.getCode() + "]已经存在！");
		}

		TEntity tentity = vo2po(entity);

		// 如果不是根实体，设置实体与所有上级关系
		if (!BlankUtils.isBlank(entity.getParent())) {
			List<TEntityRelation> relations = entityRelationManageDao.getParentRelation(entity.getParent().getId());
			for (TEntityRelation relation : relations) {
				tentity.getParentRelation().add(new TEntityRelation(relation.getParentEntity(), tentity, relation.getDepth() + 1));
			}
		}

		// 设置自己和自己的关系
		tentity.getParentRelation().add(new TEntityRelation(tentity, tentity, 0));

		return entityManageDao.addEntity(tentity);
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#updateEntity(com.eelpo
	 *      .cmmp.uac.dao.vo.Entity)
	 */
	@Override
	public void updateEntity(Entity entity) throws ServiceException {
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#deleteEntity(com
	 *      .eelpo.cmmp.uac.dao.vo.Entity)
	 */
	@Override
	public void deleteEntity(Entity entity) throws ServiceException {
	}

	/**
	 * (non-Javadoc)
	 * 
	 * @see com.eelpo.cmmp.uac.services.IEntityManageService#getMenuEntities(java.lang.String)
	 */
	@Override
	public DefaultTreeModel getMenuEntities(String userId) throws ServiceException {

		TUser user = userManageDao.getUserById(userId);

		if (BlankUtils.isBlank(user)) {
			throw new ServiceException("用户不存在！");
		}

		List<TEntity> entities = new ArrayList<TEntity>();

		if (user.getSuperManager()) {
			entities = entityManageDao.getMenuEntities();
		} else {
			entities = entityManageDao.getMenuEntities(userId);
		}

		return generateTreeModel(entities);
	}

	/**
	 * 生成树结构
	 * 
	 * @param entities
	 *            实体集合
	 * @return 返回树模型
	 */
	private DefaultTreeModel generateTreeModel(List<TEntity> entities) {
		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
		Map<TEntity, DefaultMutableTreeNode> nodeMap = new HashMap<TEntity, DefaultMutableTreeNode>();
		for (TEntity e : entities) {
			if (entities.contains(e.getParent())) {
				if (nodeMap.containsKey(e.getParent())) {
					if (nodeMap.containsKey(e)) {
						nodeMap.get(e.getParent()).add(nodeMap.get(e));
					} else {
						DefaultMutableTreeNode node = new DefaultMutableTreeNode(po2vo(e));
						nodeMap.get(e.getParent()).add(node);
						nodeMap.put(e, node);
					}
				} else {
					if (nodeMap.containsKey(e)) {
						DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(po2vo(e.getParent()));
						parentNode.add(nodeMap.get(e));
						nodeMap.put(e.getParent(), parentNode);
					} else {
						DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(po2vo(e.getParent()));
						DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(po2vo(e));
						parentNode.add(childNode);
						nodeMap.put(e, childNode);
						nodeMap.put(e.getParent(), parentNode);
					}
				}
			} else {
				TEntityRelation relation = null;
				for (TEntityRelation r : e.getParentRelation()) {
					if (entities.contains(r.getParentEntity()) && r.getDepth() != 0) {
						if (BlankUtils.isBlank(relation) || relation.getDepth() > r.getDepth()) {
							relation = r;
						}
					}
				}

				if (BlankUtils.isBlank(relation)) {
					if (nodeMap.containsKey(e)) {
						rootNode.add(nodeMap.get(e));
					} else {
						DefaultMutableTreeNode node = new DefaultMutableTreeNode(po2vo(e));
						nodeMap.put(e, node);
						rootNode.add(node);
					}
				} else {
					if (nodeMap.containsKey(relation.getParentEntity())) {
						if (nodeMap.containsKey(e)) {
							nodeMap.get(relation.getParentEntity()).add(nodeMap.get(e));
						} else {
							DefaultMutableTreeNode node = new DefaultMutableTreeNode(po2vo(e));
							nodeMap.get(relation.getParentEntity()).add(node);
							nodeMap.put(e, node);
						}
					} else {
						if (nodeMap.containsKey(e)) {
							DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(po2vo(relation.getParentEntity()));
							parentNode.add(nodeMap.get(e));
							nodeMap.put(relation.getParentEntity(), parentNode);
						} else {
							DefaultMutableTreeNode parentNode = new DefaultMutableTreeNode(po2vo(relation.getParentEntity()));
							parentNode.add(new DefaultMutableTreeNode(po2vo(e)));
							nodeMap.put(relation.getParentEntity(), parentNode);
						}
					}
				}
			}
		}

		return new DefaultTreeModel(rootNode);
	}

	/**
	 * 静态转换，不包含任何关联对象的转换
	 * 
	 * @param entity
	 *            业务实体值对象
	 * @return 返回业务实体对象
	 */
	public static TEntity vo2po(Entity entity) {

		TEntity tentity = new TEntity();

		BeanUtils.copyProperties(entity, tentity, new String[] { "status", "type", "parent" });

		tentity.setStatus(Status.valueOf(entity.getStatus()));

		if (!BlankUtils.isBlank(entity.getParent()))
			tentity.setParent(new TEntity(entity.getParent().getId()));

		if (!BlankUtils.isBlank(entity.getType()))
			tentity.setType(new TEntityType(entity.getType().getId()));

		return tentity;
	}

	/**
	 * 静态转换，不包含任何关联对象的转换
	 * 
	 * @param tentity
	 *            业务实体对象
	 * @return 返回业务实体值对象
	 */
	public static Entity po2vo(TEntity tentity) {

		Entity entity = new Entity();

		BeanUtils.copyProperties(tentity, entity, new String[] { "status", "type", "parent" });

		entity.setStatus(Status.valueOf(tentity.getStatus()));

		return entity;
	}

	/**
	 * 静态转换，不包含任何关联对象的转换
	 * 
	 * @param tentities
	 *            业务实体对象列表
	 * @return 返回业务实体值对象列表
	 */
	public static List<Entity> po2vo(List<TEntity> tentities) {
		List<Entity> entities = new ArrayList<Entity>();
		for (TEntity tentity : tentities) {
			entities.add(po2vo(tentity));
		}
		return entities;
	}
}
